package com.xh1024.demo.ddns.ddnsservice.utils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * @Description: 模拟http请求的工具类
 * @Author wangzhen
 * @Date 2020/05/20
 **/
public class HttpUtil {

    private static final String IP_OPT1="0:0:0:0:0:0:0:1";

    private static final String IP_OPT2="127.0.0.1";

    /**
     * 发起get请求
     *
     * @param uri     请求网址
     * @param param   请求参数
     * @param charSet 字符编码，默认值UTF-8
     * @return
     */
    public static String get(String uri, Map<String, String> param, String charSet) {
        String result = "";
        InputStream in = null;
        HttpURLConnection urlConn=null;
        if (charSet == null) {
            charSet = "UTF-8";
        }

        try {

            //如果传入了参数，将参数值进行编码后，拼接到URI中
            if (param != null && param.size() > 0) {
                Set<Entry<String, String>> entrySet = param.entrySet();
                uri += "?";

                for (Entry<String, String> item : entrySet) {
                    String encode = URLEncoder.encode(item.getValue(), charSet);
                    uri += (item.getKey() + "=" + encode + "&");
                }

                uri = uri.substring(0, uri.length() - 1);
            }


            URL url = new URL(uri);
            urlConn = (HttpURLConnection) url.openConnection();

            //默认是get请求
            //urlConn.setRequestMethod("get");

            //通用请求头
            urlConn.setRequestProperty("Accept", "*/*");
            urlConn.setRequestProperty("Connection", "Keep-Alive");
            urlConn.setRequestProperty("User-agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
            urlConn.setUseCaches(false);
            urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            urlConn.setRequestProperty("Charset", charSet);

            urlConn.connect();

            //如果需要，可以获取响应头
            Map<String, List<String>> headerFields = urlConn.getHeaderFields();
            Set<Entry<String, List<String>>> entrySet = headerFields.entrySet();
            for (Entry<String, List<String>> head : entrySet) {
                //System.out.println(head.getKey() + ":" + head.getValue());
            }

            //获取流，读取通道响应的数据
            in = urlConn.getInputStream();
            result = HttpUtil.readInputStream(in, charSet);

        } catch (Exception e) {
            e.printStackTrace();


        } finally {

            try {
                if(urlConn!=null){
                    urlConn.disconnect();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }


    /**
     * 发起POST请求
     *
     * @param uri     请求网址
     * @param headers 请求头,可以不传
     * @param params  要发送的参数,可以不传
     * @param charSet 采用什么编码，可以不传，默认值UTF-8
     * @return
     */
    public static String post(String uri,Map<String, String> headers, Map<String, String> params, String charSet) {
        String result = "";
        PrintWriter writer = null;
        InputStream in = null;
        HttpURLConnection urlConn=null;

        if (charSet == null) {
            charSet = "UTF-8";
        }

        try {
            URL url = new URL(uri);
            urlConn = (HttpURLConnection) url.openConnection();

            //通用请求头
            urlConn.setRequestMethod("POST");
            urlConn.setRequestProperty("Accept", "*/*");
            urlConn.setRequestProperty("Connection", "Keep-Alive");
            urlConn.setRequestProperty("User-agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
            urlConn.setUseCaches(false);
            urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            urlConn.setRequestProperty("Charset", charSet);

            //封装自定义请求头
            if(headers!=null){
                Set<String> keySet = headers.keySet();
                for(String key:keySet){
                    urlConn.setRequestProperty(key, headers.get(key));
                }
            }

            //post请求需设置如下
            urlConn.setDoInput(true);
            urlConn.setDoOutput(true);

            //如果有参数发送，进行URL编码后在发送
            if (null != params && params.size() > 0) {
                StringBuffer sb =new StringBuffer();
                writer = new PrintWriter(urlConn.getOutputStream());

                Set<Entry<String, String>> entrySet = params.entrySet();
                for (Entry<String, String> entry : entrySet) {
                    sb.append(entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), charSet) + "&");
                }

                String val=sb.toString();

                if (val.length() > 2) {
                    val = val.substring(0, val.length() - 1);
                }

                //发送的参数规则:name=%ACN%&age=15
                writer.print(val);
                writer.flush();
            }

            //如果需要，可以获取响应头
            Map<String, List<String>> headerFields = urlConn.getHeaderFields();
            Set<Entry<String, List<String>>> entrySet = headerFields.entrySet();
            for (Entry<String, List<String>> head : entrySet) {
            }

            in = urlConn.getInputStream();
            result = HttpUtil.readInputStream(in, charSet);
        } catch (MalformedURLException e) {
            e.printStackTrace();
            System.err.println(e.getMessage());

        } catch (IOException e) {
            e.printStackTrace();
            System.err.println(e.getMessage());

        } finally {

            try {
                if(urlConn!=null){
                    urlConn.disconnect();
                }
                if(writer!=null){
                    writer.close();
                }
                if (in != null) {
                    in.close();
                }

            } catch (IOException e) {
                System.err.println(e.getMessage());
            }

        }

        return result;
    }


    /**
     * 发起POST请求
     *
     * @param uri     请求网址
     * @param headers 请求头,可以不传
     * @param body    json参数
     * @param charSet 采用什么编码，默认值UTF-8
     * @return
     */
    public static String post(String uri,Map<String, String> headers, String body, String charSet) {
        String result = "";
        PrintWriter writer = null;
        InputStream in = null;
        HttpURLConnection urlConn=null;

        if (charSet == null) {
            charSet = "UTF-8";
        }

        try {
            URL url = new URL(uri);
            urlConn = (HttpURLConnection) url.openConnection();

            //通用请求头
            urlConn.setRequestMethod("POST");
            urlConn.setRequestProperty("Accept", "*/*");
            urlConn.setRequestProperty("Connection", "Keep-Alive");
            urlConn.setRequestProperty("User-agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
            urlConn.setUseCaches(false);
            urlConn.setRequestProperty("Content-Type", "application/json");
            urlConn.setRequestProperty("Charset", charSet);

            //封装自定义请求头
            if(headers!=null){
                Set<String> keySet = headers.keySet();
                for(String key:keySet){
                    urlConn.setRequestProperty(key, headers.get(key));
                }
            }

            //post请求需设置如下
            urlConn.setDoInput(true);
            urlConn.setDoOutput(true);

            if (body!=null&&body.length()>0) {
                writer = new PrintWriter(urlConn.getOutputStream());
                writer.print(body);
                writer.flush();
            }

            //如果需要，可以获取响应头
            Map<String, List<String>> headerFields = urlConn.getHeaderFields();
            Set<Entry<String, List<String>>> entrySet = headerFields.entrySet();
            System.out.println("响应头:");
            for (Entry<String, List<String>> head : entrySet) {
                System.out.println(head.getKey() + ":" + head.getValue());
            }

            in = urlConn.getInputStream();
            result = HttpUtil.readInputStream(in, charSet);
        } catch (MalformedURLException e) {
            e.printStackTrace();

        } catch (IOException e) {
            e.printStackTrace();

        } finally {

            try {
                if(urlConn!=null){
                    urlConn.disconnect();
                }
                if(writer!=null){
                    writer.close();
                }
                if (in != null) {
                    in.close();
                }

            } catch (IOException e) {
                System.err.println(e.getMessage());
            }

        }

        return result;
    }


    /**
     * post发送文件
     * @param uri       目标url
     * @param headers   自定义请求头，可以不传
     * @param params    参数 Map.put(fileName,InputStream)
     * @param charSet   传输编码，可以不传，默认UTF-8
     * @return
     */
    public static String sendFile(String uri,Map<String, String> headers, Map<String, InputStream> params, String charSet) {

        String result = "";
        if (charSet == null) {
            charSet = "UTF-8";
        }
        if (params == null) {
            return null;
        }
        OutputStream output=null;
        InputStream in=null;
        HttpURLConnection connection=null;
        try {

            // 定义数据分隔线
            String BOUNDARY = "========7d4a6d158c9";
            // 服务器的域名
            URL url = new URL(uri);
            // 发送POST请求必须设置如下两行
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Connection", "Keep-Alive");
            connection.setRequestProperty("Charset", charSet);
            connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);

            //封装自定义请求头
            if(headers!=null){
                Set<String> keySet = headers.keySet();
                for(String key:keySet){
                    connection.setRequestProperty(key, headers.get(key));
                }
            }

            // 头
            String boundary = BOUNDARY;

            // 尾
            String endBoundary = "\r\n--" + boundary + "--\r\n";

            // 2. 循环写出文件
            output = connection.getOutputStream();
            Set<Entry<String, InputStream>> set = params.entrySet();
            for (Entry<String, InputStream> item : set) {
                HttpUtil.outputFileData(output,item.getKey(),item.getValue());

            }


            output.write(endBoundary.getBytes());
            output.flush();

            //如果需要，可以获取响应头
            Map<String, List<String>> headerFields = connection.getHeaderFields();
            Set<Entry<String, List<String>>> entrySet = headerFields.entrySet();
            for (Entry<String, List<String>> head : entrySet) {
            }

            // 3. 从服务器获得回答的内容
            in = connection.getInputStream();
            result = HttpUtil.readInputStream(in, charSet);

        } catch (Exception e) {
            System.out.println("发送POST请求出现异常！" + e);
            System.err.println(e.getMessage());
        }finally {

            try {
                if(connection!=null){
                    connection.disconnect();
                }

                if(output!=null){
                    output.close();
                }

                if(in!=null){
                    in.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }


    /**
     * 读取通道响应的数据
     *
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static String readInputStream(InputStream inputStream, String charSet) throws IOException {
        StringBuilder result = new StringBuilder(256);

        int len = 0;
        byte[] bys = new byte[10240];
        while ((len = inputStream.read(bys)) != -1) {
            String string = new String(bys, 0, len,charSet);
            result.append(string);
        }

        return result.toString();
    }


    /**
     * 写出文件
     *
     * @param output    url连接通道输出流
     * @param fileName  文件名称
     * @param input     该文件的读取流
     * @return
     * @throws UnsupportedEncodingException
     * @throws IOException
     */
    public static boolean outputFileData(OutputStream output,String fileName, InputStream input) throws UnsupportedEncodingException, IOException {
        // 定义数据分隔线
        String BOUNDARY = "========7d4a6d158c9";
        String newLine = "\r\n";

        // 传输内容
        StringBuilder sb = new StringBuilder();
        sb.append("--")
                .append(BOUNDARY)
                .append(newLine)
                .append("Content-Disposition: form-data;name=\"file")// form中field的名称
                .append("\";filename=\"").append(fileName + "\"")   //上传文件的文件名，包括目录
                .append(newLine)
                .append("Content-Type:multipart/form-data")
                .append(newLine + newLine);
        String boundaryMessage = sb.toString();
        output.write(boundaryMessage.getBytes());

        // 开始真正向服务器写文件
        int len = 0;
        byte[] bys = new byte[102400];
        while ((len = input.read(bys)) != -1) {
            output.write(bys, 0, len);
        }

        return true;

    }


//    /**
//     * 获取请求真实IP
//     * @param request
//     * @return
//     */
//    public static String getIp(HttpServletRequest request) {
//
//        // 这个一般是Nginx反向代理设置的参数
//        String ip = request.getHeader("X-Real-IP");
//        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
//            ip = request.getHeader("X-Forwarded-For");
//        }
//        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
//            ip = request.getHeader("Proxy-Client-IP");
//        }
//        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
//            ip = request.getHeader("WL-Proxy-Client-IP");
//        }
//        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
//            ip = request.getRemoteAddr();
//        }
//        // 处理多IP的情况（只取第一个IP）
//        if (ip != null && ip.contains(",")) {
//            String[] ipArray = ip.split(",");
//            ip = ipArray[0];
//        }
//        if(ip!=null&&ip.equals(IP_OPT1)){
//            ip=IP_OPT2;
//        }
//
//        return ip;
//    }
//
//
//    /**
//     * 判断浏览器类型
//     * @param request
//     * @return
//     */
//    public static String getBrowserType(HttpServletRequest request) {
//        String UserAgent = request.getHeader("USER-AGENT").toLowerCase();
//        if (UserAgent != null) {
//
//            if (UserAgent.indexOf("msie") >= 0){
//                return "IE";
//            }
//
//            if (UserAgent.indexOf("chrome") >= 0){
//                return "chrome";
//            }
//
//            if (UserAgent.indexOf("firefox") >= 0){
//                return "firefox";
//            }
//
//            if (UserAgent.indexOf("safari") >= 0){
//                return "SF";
//            }
//
//        }
//        return "none";
//    }

//GET请求测试
//  public static void main(String[] args) {
//		Map<String,String> map=new LinkedHashMap<>();
//		map.put("name", "西安");
//		map.put("password", "12346");
//
//		String string = HttpUtil.get("http://127.0.0.1:9000/oss/g1",map,"UTF-8");
//		System.out.println(string);
//	}


//POST请求测试
//    public static void main(String[] args) {
//		Map<String,String> map=new LinkedHashMap<>();
//		map.put("name", "西安");
//		map.put("password", "12346");
//
//		String string = HttpUtil.post("http://127.0.0.1:9000/oss/test1",null,map,"UTF-8");
//		System.out.println(string);
//	}

//文件上传测试，目前只支持单文件上传，多个文件会合并为一个文件，此问题还未解决
//    public static void main(String[] args) throws FileNotFoundException {
//		FileInputStream f1=new FileInputStream("C:/Users/Administrator/Desktop/1V}TDLPDJ5LNQ16F$ZL`75I.png");
//		FileInputStream f2=new FileInputStream("C:/Users/Administrator/Desktop/fa68a5fb180b0f2eab77554607b60f38.jpeg");
//		Map<String,InputStream> map=new LinkedHashMap<>();
//		map.put("1V}TDLPDJ5LNQ16F$ZL`75I.png", f1);
//		map.put("fa68a5fb180b0f2eab77554607b60f38.jpeg", f2);
//
//		String string = HttpUtil.sendFile("http://127.0.0.1:8080/yuchenoss/oss/upload",,null,map,"UTF-8");
//		System.out.println(string);
//	}




}

